package com.geek.water.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.geek.water.constant.CodeConstant;
import com.geek.water.constant.MessageConstant;
import com.geek.water.constant.RedisImgConstant;
import com.geek.water.dto.UserCreateDTO;
import com.geek.water.dto.UserPermissionDTO;
import com.geek.water.dto.UserUpdateDTO;
import com.geek.water.entity.User;
import com.geek.water.result.Result;
import com.geek.water.service.UserRoleService;
import com.geek.water.service.UserService;

import com.geek.water.utils.JwtHelper;
import com.geek.water.vo.UserPageQueryVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author chenmin
 * @desc 用户管理控制器
 * @date 2025/7/24
 */
@RestController
@RequestMapping("/admin/user")
@Slf4j
@Api(tags = "后台系统-用户管理接口")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;
    private final UserRoleService userRoleService;
    private final RedisTemplate<String, Object> redisTemplate;

    @ApiOperation("获取用户信息")
    @GetMapping("info")
    public Result getUserInfo(@RequestHeader("Authorization") String authorization) {
        //请求头  以Authorization作为键，以Bearer accessToken作为值
        if (StringUtils.hasLength(authorization)) {
            String accessToken = authorization.substring(7);
            //获取用户ID
            Long userId = JwtHelper.getUserId(accessToken);
            //查询用户信息
            User user = userService.getUserWithRoles(userId);
            if (!ObjectUtils.isEmpty(user)) {
                log.info("获取用户信息成功，用户ID: {}", userId);
                return new Result(CodeConstant.SUCCESS, MessageConstant.GET_USER_SUCCESS, user);
            }
        }
        return new Result(CodeConstant.FAIL, MessageConstant.GET_USER_FAIL);
    }

    @ApiOperation("分页查询用户列表")
    @PreAuthorize("hasAuthority('user:view')")
    @GetMapping("page")
    public Result page(UserPageQueryVO userPageQueryVO) {
        try {
            Page<User> page = userService.findPageWithRoles(userPageQueryVO);
            if (page != null) {
                log.info("查询用户列表成功，总记录数: {}", page.getTotal());
                return new Result(CodeConstant.SUCCESS, MessageConstant.QUERY_USER_LIST_SUCCESS, page);
            }
            return new Result(CodeConstant.FAIL, MessageConstant.QUERY_USER_LIST_FAIL);
        } catch (Exception e) {
            log.error("查询用户列表失败", e);
            return new Result(CodeConstant.FAIL, MessageConstant.QUERY_USER_LIST_FAIL + ": " + e.getMessage());
        }
    }

    @ApiOperation("根据ID查询用户")
    @PreAuthorize("hasAuthority('user:view')")
    @GetMapping("{id}")
    public Result findById(@PathVariable Long id) {
        try {
            User user = userService.getUserWithRoles(id);
            if (user != null) {
                log.info("查询用户成功，用户ID: {}", id);
                return new Result(CodeConstant.SUCCESS, MessageConstant.GET_USER_SUCCESS, user);
            }
            return new Result(CodeConstant.FAIL, MessageConstant.USER_NOT_EXIST);
        } catch (Exception e) {
            log.error("查询用户失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, MessageConstant.GET_USER_FAIL + ": " + e.getMessage());
        }
    }

    @ApiOperation("新增用户")
    @PreAuthorize("hasAuthority('user:operate')")
    @PostMapping
    public Result save(@RequestBody UserCreateDTO userCreateDTO) {
        try {
            // 检查用户名是否已存在
            User existingUser = userService.findByUsername(userCreateDTO.getUsername());
            if (existingUser != null) {
                return new Result(CodeConstant.FAIL, MessageConstant.USERNAME_ALREADY_EXISTS);
            }

            User user = new User();
            BeanUtils.copyProperties(userCreateDTO, user);

            // 对于系统管理员角色，customerId可以为空
            // 对于其他角色，验证customerId是否存在
            if (userCreateDTO.getRoleIds() != null && !userCreateDTO.getRoleIds().isEmpty()) {
                // 检查是否包含系统管理员角色（假设管理员角色ID为1）
                boolean isAdmin = userCreateDTO.getRoleIds().contains(1L);
                if (!isAdmin && userCreateDTO.getCustomerId() == null) {
                    return new Result(CodeConstant.FAIL, MessageConstant.NON_ADMIN_MUST_SELECT_CUSTOMER);
                }
            }

            boolean success = userService.save(user);
            if (success) {
                // 分配角色
                if (userCreateDTO.getRoleIds() != null && !userCreateDTO.getRoleIds().isEmpty()) {
                    userRoleService.assignRolesToUser(user.getId(), userCreateDTO.getRoleIds());
                }

                // 如果用户有头像，记录到Redis中
                if (StringUtils.hasLength(user.getAvatar())) {
                    redisTemplate.opsForSet().add(RedisImgConstant.UPLOAD_DB_PIC, user.getAvatar());
                }

                log.info("新增用户成功，用户名: {}", userCreateDTO.getUsername());
                return new Result(CodeConstant.SUCCESS, MessageConstant.ADD_USER_SUCCESS);
            } else {
                return new Result(CodeConstant.FAIL, MessageConstant.ADD_USER_FAIL);
            }
        } catch (Exception e) {
            log.error("新增用户失败", e);
            return new Result(CodeConstant.FAIL, MessageConstant.ADD_USER_FAIL + ": " + e.getMessage());
        }
    }

    @ApiOperation("更新用户信息")
    @PreAuthorize("hasAuthority('user:operate')")
    @PutMapping("{id}")
    public Result updateUser(@PathVariable Long id, @RequestBody UserUpdateDTO userUpdateDTO) {
        try {
            // 检查用户是否存在
            User existingUser = userService.getById(id);
            if (existingUser == null) {
                return new Result(CodeConstant.FAIL, "用户不存在");
            }

            // 如果更新了头像，需要处理旧头像的清理
            String oldAvatar = existingUser.getAvatar();
            String newAvatar = userUpdateDTO.getAvatar();

            User user = new User();
            BeanUtils.copyProperties(userUpdateDTO, user);
            user.setId(id);

            boolean success = userService.updateById(user);
            if (success) {
                // 更新角色
                userRoleService.assignRolesToUser(id, userUpdateDTO.getRoleIds());

                // 处理头像更新后的Redis记录
                if (StringUtils.hasLength(newAvatar) && !newAvatar.equals(oldAvatar)) {
                    // 如果新头像不为空且与旧头像不同
                    if (StringUtils.hasLength(newAvatar)) {
                        // 将新头像添加到数据库中已保存的图片集合中
                        redisTemplate.opsForSet().add(RedisImgConstant.UPLOAD_DB_PIC, newAvatar);
                    }

                    // 如果旧头像不为空，从数据库中已保存的图片集合中移除
                    if (StringUtils.hasLength(oldAvatar)) {
                        redisTemplate.opsForSet().remove(RedisImgConstant.UPLOAD_DB_PIC, oldAvatar);
                    }
                }

                log.info("更新用户信息成功，用户ID: {}", id);
                return new Result(CodeConstant.SUCCESS, "用户信息更新成功");
            } else {
                return new Result(CodeConstant.FAIL, "用户信息更新失败");
            }
        } catch (Exception e) {
            log.error("更新用户信息失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, "更新用户信息失败: " + e.getMessage());
        }
    }

    @ApiOperation("删除用户")
    @PreAuthorize("hasAuthority('user:operate')")
    @DeleteMapping("{id}")
    public Result deleteById(@PathVariable Long id) {
        try {
            // 检查用户是否存在
            User existingUser = userService.getById(id);
            if (existingUser == null) {
                return new Result(CodeConstant.FAIL, "用户不存在");
            }

            // 先删除用户角色关联
            userRoleService.deleteRolesByUserId(id);

            boolean success = userService.removeById(id);
            if (success) {
                // 如果用户有头像，从Redis中清理相关记录
                if (StringUtils.hasLength(existingUser.getAvatar())) {
                    redisTemplate.opsForSet().remove(RedisImgConstant.UPLOAD_DB_PIC, existingUser.getAvatar());
                    redisTemplate.opsForSet().remove(RedisImgConstant.UPLOAD_PIC, existingUser.getAvatar());
                    redisTemplate.delete(existingUser.getAvatar() + "_provider");
                }

                log.info("删除用户成功，用户ID: {}", id);
                return new Result(CodeConstant.SUCCESS, "删除用户成功");
            } else {
                return new Result(CodeConstant.FAIL, "删除用户失败");
            }
        } catch (Exception e) {
            log.error("删除用户失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, "删除用户失败: " + e.getMessage());
        }
    }

    @ApiOperation("更新用户状态")
    @PutMapping("{id}/status")
    public Result updateUserStatus(@PathVariable Long id, @RequestParam String status) {
        try {
            if (!"enabled".equals(status) && !"disabled".equals(status)) {
                return new Result(CodeConstant.FAIL, "状态值无效，只能是enabled或disabled");
            }

            boolean success = userService.updateUserStatus(id, status);
            if (success) {
                log.info("更新用户状态成功，用户ID: {}，状态: {}", id, status);
                return new Result(CodeConstant.SUCCESS, "更新用户状态成功");
            } else {
                return new Result(CodeConstant.FAIL, "更新用户状态失败");
            }
        } catch (Exception e) {
            log.error("更新用户状态失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, "更新用户状态失败: " + e.getMessage());
        }
    }

    @ApiOperation("重置用户密码")
    @PutMapping("{id}/password")
    public Result resetPassword(@PathVariable Long id, @RequestParam String newPassword) {
        try {
            if (!StringUtils.hasLength(newPassword)) {
                return new Result(CodeConstant.FAIL, MessageConstant.PASSWORD_CANNOT_BE_EMPTY);
            }

            boolean success = userService.resetPassword(id, newPassword);
            if (success) {
                log.info("重置用户密码成功，用户ID: {}", id);
                return new Result(CodeConstant.SUCCESS, MessageConstant.RESET_PASSWORD_SUCCESS);
            } else {
                return new Result(CodeConstant.FAIL, MessageConstant.RESET_PASSWORD_FAIL);
            }
        } catch (Exception e) {
            log.error("重置用户密码失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, MessageConstant.RESET_PASSWORD_FAIL + ": " + e.getMessage());
        }
    }

    @ApiOperation("获取用户权限")
    @GetMapping("{id}/permissions")
    public Result getUserPermissions(@PathVariable Long id) {
        try {
            // 检查用户是否存在
            User user = userService.getById(id);
            if (user == null) {
                return new Result(CodeConstant.FAIL, MessageConstant.USER_NOT_EXIST);
            }

            // 从数据库中查询用户的真实权限数据
            List<Integer> permissions = userService.getUserPermissionIds(id);

            log.info("获取用户权限成功，用户ID: {}, 权限数量: {}", id, permissions.size());
            return new Result(CodeConstant.SUCCESS, MessageConstant.GET_USER_PERMISSIONS_SUCCESS, permissions);
        } catch (Exception e) {
            log.error("获取用户权限失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, MessageConstant.GET_USER_PERMISSIONS_FAIL + ": " + e.getMessage());
        }
    }

    @ApiOperation("保存用户权限")
    @PutMapping("{id}/permissions")
    public Result saveUserPermissions(@PathVariable Long id, @RequestBody UserPermissionDTO userPermissionDTO) {
        try {
            // 检查用户是否存在
            User user = userService.getById(id);
            if (user == null) {
                return new Result(CodeConstant.FAIL, MessageConstant.USER_NOT_EXIST);
            }

            // 验证权限ID列表
            List<Integer> permissionIds = userPermissionDTO.getPermissionIds();
            if (permissionIds == null || permissionIds.isEmpty()) {
                return new Result(CodeConstant.FAIL, MessageConstant.PERMISSION_IDS_CANNOT_BE_EMPTY);
            }

            // 调用服务层保存用户权限
            boolean success = userService.saveUserPermissions(id, permissionIds);
            if (!success) {
                log.warn("保存用户权限返回失败，用户ID: {}", id);
                return new Result(CodeConstant.FAIL, MessageConstant.SAVE_USER_PERMISSIONS_FAIL);
            }

            log.info("保存用户权限成功，用户ID: {}, 权限数量: {}, 操作备注: {}",
                    id, permissionIds.size(), userPermissionDTO.getRemark());
            return new Result(CodeConstant.SUCCESS, MessageConstant.SAVE_USER_PERMISSIONS_SUCCESS);
        } catch (Exception e) {
            log.error("保存用户权限失败，用户ID: {}", id, e);
            return new Result(CodeConstant.FAIL, MessageConstant.SAVE_USER_PERMISSIONS_FAIL + ": " + e.getMessage());
        }
    }
}
